#include <sdk.h>
#include "compilerC.h"
#include <wx/intl.h>
#include <wx/regex.h>
#include <wx/config.h>
#include <wx/fileconf.h>
#include <wx/msgdlg.h>
#include <wx/filename.h>
#include <wx/filefn.h>
#include "manager.h"
#include "macrosmanager.h"
#include "logmanager.h"
#include "compilerCgenerator.h"
#include <configmanager.h>

CompilerC::CompilerC( const wxString& name, const wxString& ID ) : Compiler( name, ID ) {
  m_Weight = 4;
  Reset();
}

CompilerC::~CompilerC() {
}

Compiler * CompilerC::CreateCopy() {
  return ( new CompilerC( *this ) );
}

CompilerCommandGenerator* CompilerC::GetCommandGenerator( M_Code_Project *project ) {
  CompilerCGenerator *generator = new CompilerCGenerator;
  generator->Init( project );
  return generator;
}

AutoDetectResult CompilerC::AutoDetectInstallationDir() {
  wxString pathValues;
  wxGetEnv( _T( "PATH" ), &pathValues );
  if( !pathValues.IsEmpty() ) {
    wxString sep =  _T( ":" );
    wxChar pathSep =  _T( '/' );
    wxArrayString pathArray = GetArrayFromString( pathValues, sep );
    for( size_t i = 0; i < pathArray.GetCount(); ++i ) {
      if( wxFileExists( pathArray[i] + pathSep + m_Programs.C ) ) {
        if( pathArray[i].AfterLast( pathSep ).IsSameAs( _T( "bin" ) ) ) {
          m_MasterPath = pathArray[i].BeforeLast( pathSep );
          return adrDetected;
        }
      }
    }
  }
  wxString sep = wxFileName::GetPathSeparator();
  m_MasterPath = _T( "/usr" );
  AutoDetectResult ret = wxFileExists( m_MasterPath + sep + _T( "bin" ) + sep + m_Programs.C ) ? adrDetected : adrGuessed;
  SetVersionString();
  return ret;
}

void CompilerC::SetVersionString() {
  wxArrayString output, errors;
  wxString sep = wxFileName::GetPathSeparator();
  wxString master_path = m_MasterPath;
  wxString compiler_exe = m_Programs.C;
  ConfigManager* cmgr = Manager::Get()->GetConfigManager( _T( "compiler" ) );
  if( cmgr ) {
    wxString settings_path;
    wxString compiler_path;
    if( GetParentID().IsEmpty() ) {
      settings_path = _T( "/sets/" ) + GetID() + _T( "/master_path" );
      compiler_path = _T( "/sets/" ) + GetID() + _T( "/c_compiler" );
    } else {
      settings_path = _T( "/user_sets/" ) + GetID() + _T( "/master_path" );
      compiler_path = _T( "/user_sets/" ) + GetID() + _T( "/c_compiler" );
    }
    cmgr->Read( settings_path, &master_path );
    cmgr->Read( compiler_path, &compiler_exe );
  }
  if( master_path.IsEmpty() ) {
    master_path = _T( "/usr" );
  }
  wxString gcc_command = master_path + sep + _T( "bin" ) + sep + compiler_exe;
  Manager::Get()->GetMacrosManager()->ReplaceMacros( gcc_command );
  if( !wxFileExists( gcc_command ) ) {
    return;
  }
  int flags = wxEXEC_SYNC;
  flags |= wxEXEC_NODISABLE;
  long result = wxExecute( gcc_command + _T( " --version" ), output, errors, flags );
  if( result != 0 ) {
  } else {
    if( output.GetCount() > 0 ) {
      wxRegEx reg_exp;
      if( reg_exp.Compile( _T( "[0-9][.][0-9][.][0-9]" ) ) && reg_exp.Matches( output[0] ) ) {
        m_VersionString = reg_exp.GetMatch( output[0] );
      } else {
        m_VersionString = output[0].Mid( 10 );
        m_VersionString = m_VersionString.Left( 5 );
        m_VersionString.Trim( false );
      }
    }
  }
}
